home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / dsizedb.com / DIRSIZE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-27  |  5.6 KB  |  227 lines

  1. /*
  2.  * Program: DIRSIZE / Author: David Bennett / Date: 6-27-90 / Version: 1.0
  3.  *
  4.  *
  5.  * Usage:
  6.  *
  7.  *     DIRSIZE {-n} <directory spec>
  8.  *
  9.  *     Where :
  10.  *
  11.  *         -n : Specifys no sub-directory recursion.  Only the specified
  12.  *              directory is shown.
  13.  *
  14.  * Description:
  15.  *
  16.  *   This program will display a listing of directory and subdirectories
  17.  *   specified in <directory spec>.  The listing contains the name of
  18.  *   the directory the number of files in that directory and the total
  19.  *   size of all files in bytes.  A total is printed at the end.
  20.  *
  21.  * Comments & Suggestions:
  22.  *
  23.  *   David Bennett
  24.  *   Bennett Software Solutions
  25.  *   151 West Geospace Drive
  26.  *   Independence, MO  64056
  27.  *
  28.  *   CIS: 74635,1671
  29.  *   Fido: 1:280/307
  30.  */
  31.  
  32. #include <alloc.h>
  33. #include <ctype.h>
  34. #include <dir.h>
  35. #include <dos.h>
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39.  
  40. #define MAX_DIR    512        /* Maximum directories supported */
  41.  
  42. const char *author="(c) David H. Bennett, 1990";
  43. const char *ver="Version 1.0 - 6/25/90";
  44.  
  45. /*
  46.  * Directory sizing structure
  47.  */
  48. typedef struct {
  49.     char *name;                    /* Name of the directory */
  50.     long size;                  /* Cummulative size of all files in dir */
  51.     int files;                  /* Number of files in dir */
  52. } DOSDIR;
  53.  
  54. /*
  55.  * Fill the directory array and return the number of diretories in the
  56.  * system.  Returns -1 on memory error.  Record zero of the array holds
  57.  * the totals of all directories.
  58.  *
  59.  * dname   : name of the start directory
  60.  * dn      : directory counter, set to zero before calling
  61.  * direc   : allocated array of pointers to (unallocated) DOSDIR structs
  62.  * slots   : number of pointers allocated in 'direc'
  63.  * nlen    : set to 0 before calling, is set to the largest dir name length
  64.  * recurse : If directory recursion is to take place.
  65.  *
  66.  */
  67. int sizedir(char *dname,int *dn,DOSDIR **direc,int slots,int *nlen,int recurse)
  68. {
  69.     /*
  70.      * Directory search attriubte
  71.      */
  72.     static const char srchattr = (FA_RDONLY|FA_HIDDEN|FA_SYSTEM| \
  73.                                     FA_DIREC|FA_ARCH);
  74.  
  75.     char fspec[MAXPATH];    /* Wildcard file spec for search */
  76.     struct ffblk fb;        /* used in findfirst/next functions */
  77.     int done;                /* end of directory check flag */
  78.     DOSDIR *dir;            /* Alias of direc[dn] for code readability */
  79.  
  80.     /*
  81.      * Check to see that number of directories hasn't outgrown our array
  82.      * of pointers.
  83.      */
  84.     if (*dn > slots) return(-1);
  85.  
  86.     /*
  87.      * Check and make sure the array of pointers has been allocated
  88.      */
  89.     if (!direc) return(-1);
  90.  
  91.     /*
  92.      * Allocate the totals directory
  93.      */
  94.     if (*dn == 0) {
  95.         dir = direc[0] = (DOSDIR *) malloc(sizeof(DOSDIR));
  96.         if (!dir) return(-1);
  97.         strcpy(fspec, "Totals");
  98.         dir->name = (char *) malloc(strlen(fspec)+1);
  99.         if (!dir->name) return(-1);
  100.         strcpy(dir->name, fspec);
  101.         direc[0]->files = 0;
  102.         direc[0]->size = 0;
  103.     }
  104.  
  105.     /*
  106.      * Allocate the space for this directory
  107.      */
  108.     (*dn)++;            /* Add this directory to the directory counter */
  109.  
  110.     dir = direc[*dn] = (DOSDIR *) malloc(sizeof(DOSDIR));
  111.     if (!dir) return(-1);
  112.     dir->name = (char *) malloc(strlen(dname)+1);
  113.     if (!dir->name) return(-1);
  114.  
  115.     /*
  116.      * Initialize the directory record
  117.      */
  118.     strcpy(dir->name, dname);
  119.     dir->size = 0;
  120.     dir->files = 0;
  121.  
  122.     /*
  123.      * Update maximum directory name length for output
  124.      */
  125.     *nlen = max(*nlen, strlen(dir->name));
  126.  
  127.     /*
  128.      * Add wildcard spec to the directory name
  129.      */
  130.     strcpy(fspec, dir->name);
  131.     strcat(fspec, "*.*");        /* Look for all files */
  132.  
  133.     /*
  134.      * Scan the entire directory structure
  135.      */
  136.     done = findfirst(fspec, &fb, srchattr);
  137.     while (!done) {
  138.         do {
  139.             if (!strcmp(fb.ff_name,".")) break;        /* Skip curr/parent specs */
  140.             if (!strcmp(fb.ff_name,"..")) break;
  141.             if ((fb.ff_attrib & FA_DIREC) && recurse) {     /* Another dir? */
  142.                 strcpy(fspec, dname);
  143.                 strcat(fspec, fb.ff_name);
  144.                 strcat(fspec, "\\");                        /* RECURSE */
  145.                 sizedir(fspec, dn, direc, slots, nlen, recurse);
  146.             }
  147.             else {                                    /* File */
  148.                 (dir->files)++;
  149.                 dir->size += fb.ff_fsize;
  150.  
  151.                 (direc[0]->files)++;
  152.                 (direc[0]->size) += fb.ff_fsize;
  153.             }
  154.         } while (0);
  155.         done = findnext(&fb);
  156.     }
  157.     return(*dn);
  158. }
  159.  
  160. /*
  161.  * main() program entry point
  162.  *
  163.  */
  164. void main(int argc, char **argv)
  165. {
  166.     char startdir[MAXPATH]="\\";
  167.     int i, numdirs=0;
  168.     DOSDIR **direc=NULL;                /* The directories array */
  169.     int nlen=63;                        /* Maximum name length */
  170.     int recurse=1;                        /* Recurse sub-dirs by default */
  171.  
  172.     /*
  173.      * Check command line for starting directory
  174.      */
  175.     for (i=1; i < argc; i++) {
  176.  
  177.         if (argv[i][0] == '-') switch (toupper(argv[i][1])) {
  178.  
  179.             case 'N' :
  180.                 recurse = 0;
  181.                 break;
  182.  
  183.             /* Add other command line options here */
  184.  
  185.         }
  186.         else {                /* Process the directory spec */
  187.             strcpy(startdir, argv[i]);
  188.             strupr(startdir);
  189.             if (startdir[strlen(startdir)-1] != '\\') strcat(startdir, "\\");
  190.         }
  191.     }
  192.  
  193.     /*
  194.      * Allocate the array of pointers
  195.      */
  196.     direc = (DOSDIR **) calloc(MAX_DIR, sizeof(DOSDIR *));
  197.  
  198.     /*
  199.      * Calculate the size of the directorys
  200.      */
  201.     sizedir(startdir, &numdirs, direc, MAX_DIR, &nlen, recurse);
  202.     if (numdirs == -1) {
  203.         fprintf(stderr, "Not enough memory!\n");
  204.         exit(1);
  205.     }
  206.  
  207.     /*
  208.      * Print header
  209.      */
  210.     printf("%-*s %5s %9s\n\n", nlen, "Dir Name", "Files", "Size");
  211.  
  212.     /*
  213.      * Loop for each directory in the array
  214.      */
  215.     for (i=1; i <= numdirs; i++) {
  216.         printf("%-*s %5d %9ld\n", nlen, direc[i]->name, direc[i]->files,\
  217.                         direc[i]->size);
  218.     }
  219.  
  220.     /*
  221.      * Print totals
  222.      */
  223.     printf("\nA total of %d directories containing ", numdirs);
  224.     printf("%d files, ", direc[0]->files);
  225.     printf("Total bytes used %ld\n", direc[0]->size);
  226. }
  227.